package com.jsmile.cloud.goodscenter.spu.repo;

import java.util.List;
import java.util.Objects;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsmile.cloud.goodscenter.api.enums.GoodsCodeEnum;
import com.jsmile.cloud.goodscenter.api.enums.SpuImageTypeEnum;
import com.jsmile.cloud.goodscenter.api.exception.GoodsException;
import com.jsmile.cloud.goodscenter.api.req.spu.ReqSpuQuery;
import com.jsmile.cloud.goodscenter.spu.dao.SkuInfoDao;
import com.jsmile.cloud.goodscenter.spu.dao.SkuSpecDao;
import com.jsmile.cloud.goodscenter.spu.dao.SpuDao;
import com.jsmile.cloud.goodscenter.spu.dao.SpuImageDao;
import com.jsmile.cloud.goodscenter.spu.model.SkuInfo;
import com.jsmile.cloud.goodscenter.spu.model.Spu;
import com.jsmile.mall.api.enums.JSmileCacheEnum;
import com.jsmile.mall.api.exception.ExceptionKit;
import com.jsmile.mall.api.kit.DateKit;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 龚亮
 * @version 1.0
 * @desc 为了薪资破万，还是睡一会儿吧...!
 * @date 2020年06月04日 03:56:49
 */
@Service
@Slf4j
@Transactional(readOnly = true, rollbackFor = Exception.class)
@AllArgsConstructor
public class SpuSearchRepository extends ServiceImpl<SpuDao, Spu> {

    private final SkuInfoDao skuInfoDao;
    private final SkuSpecDao skuSpecDao;
    private final SpuImageDao spuImageDao;

    @Cacheable(value = JSmileCacheEnum.JSmileCacheName.oneMonth, key = "'spu_'+#spuId+'tenantId'+#tenantId")
    public Spu getSpu(long spuId, long tenantId) {
        Spu spu = this.baseMapper.findOneBySpuIdAndTenantId(spuId, tenantId);
        if (null == spu) {
            throw new GoodsException(GoodsCodeEnum.SPU_NOT_EXISTS);
        }
        List<SkuInfo> skuLis = skuInfoDao.findBySpuIdAndTenantId(spuId, tenantId);
        skuLis.forEach(x -> {
            x.setSkuSpecs(skuSpecDao.findBySkuIdAndSpuId(x.getSkuId(), x.getSpuId()));
        });
        spu.setSkuList(skuLis);
        spu.setImageUrls(spuImageDao.findBySpuIdAndType(spuId, SpuImageTypeEnum.HEAD.getValue()));
        spu.setImageDetailUrls(spuImageDao.findBySpuIdAndType(spuId, SpuImageTypeEnum.DETAIL.getValue()));
        return spu;
    }

    @Cacheable(value = JSmileCacheEnum.JSmileCacheName.oneMonth, key = "'spu_'+#spuId+'tenantId'+#tenantId")
    public Spu getSimpleSpu(long spuId, long tenantId) {
        Spu spu = this.baseMapper.findOneBySpuIdAndTenantId(spuId, tenantId);
        ExceptionKit.checkNotNull(spu, GoodsCodeEnum.SPU_NOT_EXISTS.getResCode(), GoodsCodeEnum.SPU_NOT_EXISTS.getResMsg());
        return spu;
    }

    public IPage<Spu> pageQuery(ReqSpuQuery reqSpuQuery) {
        return this.page(reqSpuQuery.getPage(), getQueryWrapper(reqSpuQuery));
    }

    private Wrapper getQueryWrapper(ReqSpuQuery reqSpuQuery) {
        return new QueryWrapper<Spu>().lambda().eq(null != reqSpuQuery.getSupplyId(), Spu::getSupplyId, reqSpuQuery.getSupplyId())
            .eq(null != reqSpuQuery.getCategoryId(), Spu::getCategoryId, reqSpuQuery.getCategoryId())
            .eq(null != reqSpuQuery.getBrandId(), Spu::getBrandId, reqSpuQuery.getBrandId())
            .eq(null != reqSpuQuery.getPublishStatus(), Spu::getPublishStatus, reqSpuQuery.getPublishStatus())
            .eq(null != reqSpuQuery.getSaleStatus(), Spu::getSaleStatus, reqSpuQuery.getSaleStatus())
            .eq(null != reqSpuQuery.getSaleFlag(), Spu::getSaleFlag, reqSpuQuery.getSaleFlag())
            .eq(null != reqSpuQuery.getReviewStatus(), Spu::getReviewStatus, reqSpuQuery.getReviewStatus())
            .eq(null != reqSpuQuery.getHasShow(), Spu::getHasShow, reqSpuQuery.getHasShow()).like(Objects.nonNull(reqSpuQuery.getSpuNo()), Spu::getSpuNo, reqSpuQuery.getSpuNo())
            .eq(null != reqSpuQuery.getCurTenantId(), Spu::getTenantId, reqSpuQuery.getCurTenantId())
            .like(Objects.nonNull(reqSpuQuery.getSpuName()), Spu::getSpuName, reqSpuQuery.getSpuName())
            .like(Objects.nonNull(reqSpuQuery.getSupplyName()), Spu::getSupplyName, reqSpuQuery.getSupplyName())
            .ge(null != reqSpuQuery.getStartDate(), Spu::getCreateTime, DateKit.beginOfDay(reqSpuQuery.getStartDate()))
            .le(null != reqSpuQuery.getEndDate(), Spu::getCreateTime, DateKit.endOfDay(reqSpuQuery.getEndDate())).orderByDesc(Spu::getCreateTime);// sort,createTime倒序
    }
}
